package com.yanqu.road.server.manager.palace;

import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.decoration.DecorationSimple;
import com.yanqu.road.entity.enums.activity.palace.ePalaceAideDismissType;
import com.yanqu.road.entity.enums.eActivityConfigType;
import com.yanqu.road.entity.estatewar.palace.*;
import com.yanqu.road.entity.log.cross.LogPalaceBattle;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.bussiness.palace.PalaceBussiness;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.estatewar.EstateWarProto;
import com.yanqu.road.server.CrossBattleServer;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.config.GoodsMgr;
import com.yanqu.road.server.manager.log.CrossAutoLogMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.UUIDHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class CrossPalaceActivity {
    private ActivityInfo activityInfo;
    private Map<Integer, PalaceFloorConfig> palaceFloorConfigMap;
    private Map<Integer, PalaceFloorInfo> palaceFloorInfoMap;
    private List<PalaceBattleNotice> palaceBattleNoticeList;
    private Map<Long, Map<String, PalaceAideJoinApply>> aideJoinApplyMap;  //幕宾申请集合
    private Map<Long, List<PalaceUserData>> palaceAideMap;
    private Map<Long, PalaceUserData> palaceUserDataMap;
    private Map<Long, Map<Long, PalaceAideDismissData>> palaceAideDismissDataMap;

    private int PALACE_DAILY_REWARD_ITEM_ID;
    private int PALACE_LEVEL_LIMIT;
    private String PALACE_WORSHIP_REWARD_PARAM;
    private int PALACE_SHOW_NUM;
    private List<Integer> PALACE_TITLE_ADDITION_LIST = new ArrayList<>();

    public boolean init(ActivityInfo activityInfo){
        palaceFloorInfoMap = PalaceBussiness.getPalaceFloorInfoMap(activityInfo.getActivityId());
        palaceBattleNoticeList = PalaceBussiness.getPalaceBattleNoticeList(activityInfo.getActivityId(), GameConfig.PALACE_BATTLE_NOTICE_MAX_COUNT);
        palaceAideDismissDataMap = PalaceBussiness.getPalaceAideDismissDataMap(activityInfo.getActivityId());

        Map<Long, List<PalaceUserData>> tempPalaceAideMap = new ConcurrentHashMap<>();
        Map<Long, PalaceUserData> tempPalaceUserDataMap = new ConcurrentHashMap<>();
        PalaceBussiness.getPalaceUserDataMap(activityInfo.getActivityId(), tempPalaceAideMap, tempPalaceUserDataMap);
        palaceAideMap = tempPalaceAideMap;
        palaceUserDataMap = tempPalaceUserDataMap;

        aideJoinApplyMap = new ConcurrentHashMap<>();

        //加载配置
        return reloadActivity(activityInfo);
    }

    public boolean reloadActivity(ActivityInfo activityInfo){
        //加载配置
        palaceFloorConfigMap = ActivityBussiness.getPalaceFloorConfigMap(activityInfo.getActivityId());

        List<Integer> activityIdList = new ArrayList<>();
        activityIdList.add(activityInfo.getActivityId());

        // 其他配置
        Map<String, ActivityConfig> activityConfigMap = ActivityBussiness.getActivityConfigMap(activityIdList).get(activityInfo.getActivityId());
        if(null != activityConfigMap) {
            PALACE_SHOW_NUM = ActivityHelper.getActivityConfigIntValue(activityConfigMap, eActivityConfigType.PALACE_SHOW_NUM);
            PALACE_DAILY_REWARD_ITEM_ID = ActivityHelper.getActivityConfigIntValue(activityConfigMap, eActivityConfigType.PALACE_DAILY_REWARD_ITEM_ID);
            PALACE_TITLE_ADDITION_LIST = ActivityHelper.getActivityConfigIntListValue(activityConfigMap, eActivityConfigType.PALACE_TITLE_ADD, "\\|");
            PALACE_LEVEL_LIMIT = ActivityHelper.getActivityConfigIntValue(activityConfigMap, eActivityConfigType.PALACE_LEVEL_LIMIT);
            PALACE_WORSHIP_REWARD_PARAM = ActivityHelper.getActivityConfigValue(activityConfigMap, eActivityConfigType.PALACE_WORSHIP_REWARD_PARAM);
        }
        this.activityInfo = activityInfo;
        return true;
    }

    public boolean save(){
        for(PalaceFloorInfo data : palaceFloorInfoMap.values()){
            if(data.isInsertOption()){
                PalaceBussiness.addPalaceFloorInfo(data);
            }else if(data.isUpdateOption()){
                PalaceBussiness.updatePalaceFloorInfo(data);
            }
        }
        List<PalaceBattleNotice> tempList;
        synchronized (palaceBattleNoticeList){
            tempList = new ArrayList<>(palaceBattleNoticeList);
        }
        for(PalaceBattleNotice data : tempList){
            if(data.isInsertOption()){
                PalaceBussiness.addPalaceBattleNotice(data);
            }
        }
        for(PalaceUserData data : palaceUserDataMap.values()){
            if(data.isInsertOption()){
                PalaceBussiness.addPalaceUserData(data);
            }else if(data.isUpdateOption()){
                PalaceBussiness.updatePalaceUserData(data);
            }
        }
        for(Map<Long, PalaceAideDismissData> dataMap : palaceAideDismissDataMap.values()){
            for(PalaceAideDismissData data :dataMap.values()){
                if(data.isInsertOption()){
                    PalaceBussiness.addPalaceAideDismissData(data);
                }else if(data.isUpdateOption()){
                    PalaceBussiness.updatePalaceAideDismissData(data);
                }
            }
        }
        return true;
    }

    public int getActivityId(){
        if(null != activityInfo){
            return activityInfo.getActivityId();
        }
        return 0;
    }

    public boolean isPalaceActivityInTime(){
        return ActivityHelper.activityInShowTime(activityInfo);
    }

    public int getPalaceFloorList(long userId, long serverId, int pageNum, long time){
        List<PalaceFloorInfo> dataList = new ArrayList<>();
        int startIndex = pageNum * PALACE_SHOW_NUM + 1;
        int endIndex = (pageNum + 1) * PALACE_SHOW_NUM;
        for(int i = startIndex; i <= endIndex; i++){
            PalaceFloorInfo data = palaceFloorInfoMap.get(i);
            if(null != data){
                if(data.getUserId() > 0) {
                    if (data.getModifyTime() > time
                            || CrossUserMgr.getCrossUserBaseInfoModiftyTime(data.getUserId()) > time
                            || getAideLastJoinTime(data.getUserId()) > time
                            || getLastPalaceAideDismissTime(data.getUserId()) > time
                    ) {
                        dataList.add(data);
                    }
                }else {
                    if(data.getModifyTime() > time){
                        dataList.add(data);
                    }
                }
            }
        }
        EstateWarProto.PalaceFloorListRespMsg.Builder respMsg = EstateWarProto.PalaceFloorListRespMsg.newBuilder();
        for(PalaceFloorInfo data : dataList){
            EstateWarProto.PalaceFloorTempMsg.Builder msg = parsePalaceFloorTempMsg(data);
            if(null != msg) {
                respMsg.addDataList(msg);
            }
        }
        respMsg.setRet(0);
        respMsg.setTime(System.currentTimeMillis());
        respMsg.setPageNum(pageNum);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.U_PALACE_FLOOR_LIST, respMsg);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
        return 0;
    }

    public List<PalaceBattleNotice> getPalaceBattleNoticeList(){
        List<PalaceBattleNotice> dataList;
        synchronized (palaceBattleNoticeList) {
            dataList = new ArrayList<>(palaceBattleNoticeList);
        }
        int length = dataList.size();
        if(length > GameConfig.PALACE_BATTLE_NOTICE_MAX_COUNT){
            dataList.sort(Comparator.comparingLong(PalaceBattleNotice::getNoticeTime));
            dataList = dataList.subList(length - GameConfig.PALACE_BATTLE_NOTICE_MAX_COUNT, length);
        }
        return dataList;
    }

    public int battle(long serverId, long userId, UserBaseInfo myUserInfo, long enemyServerId, long enemyUserId, int pos,
                      BigInteger myAbility, List<DecorationSimple> myDecorationSimpleList){
        //更新一下玩家数据，跟业务无关
        CrossUserMgr.updateUserBaseInfo(userId, myUserInfo);

        boolean isWin = false;
        int myOldPos = 0;
        PalaceFloorInfo oldPalaceFloor = null;
        BigDecimal myValue;
        BigDecimal enemyValue;
        BigInteger enemyAbility;
        List<DecorationSimple> enemyDecorationSimpleList;
        List<Integer> enemyTitleList = null;
        List<Integer> myTitleList = getInTimeTitleList(myDecorationSimpleList);
        synchronized (palaceFloorInfoMap) {//锁起来，慢慢打
            for(PalaceFloorInfo data : palaceFloorInfoMap.values()){
                if(data.getUserId() == userId){
                    oldPalaceFloor = data;
                    myOldPos = data.getPos();
                    break;
                }
            }
            if(null != oldPalaceFloor){
                if(oldPalaceFloor.getPos() <= pos){
                    return GameErrorCode.E_PALACE_CAN_NOT_BATTLE_LOW_FLOOR;
                }
            }
            if(enemyUserId > 0) {
                PalaceFloorInfo palaceFloorInfo = palaceFloorInfoMap.get(pos);
                if (null == palaceFloorInfo) {
                    return GameErrorCode.E_ESTATE_WAR_FLOOR_CHANGE;
                }
                if (palaceFloorInfo.getUserId() != enemyUserId) {
                    return GameErrorCode.E_ESTATE_WAR_FLOOR_CHANGE;
                }
                enemyAbility = palaceFloorInfo.getTotalAbility();
                enemyDecorationSimpleList = palaceFloorInfo.getDecorationSimpleList();
                enemyTitleList = getInTimeTitleList(enemyDecorationSimpleList);
                //比拼赚速
                int addition = getTitleAddition(myTitleList);
                myValue = new BigDecimal(myAbility).multiply(BigDecimal.valueOf(addition)).
                        divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP);

                addition = getTitleAddition(enemyTitleList);
                enemyValue = new BigDecimal(enemyAbility).multiply(BigDecimal.valueOf(addition)).
                        divide(BigDecimal.valueOf(1000),0, BigDecimal.ROUND_UP);
                if(myValue.compareTo(enemyValue) > 0){//赢了
                    isWin = true;
                }
                if(isWin) {//变更位置
                    long nowTime = System.currentTimeMillis();
                    if (null != oldPalaceFloor) {
                        oldPalaceFloor.setUserId(enemyUserId);
                        oldPalaceFloor.setTotalAbility(palaceFloorInfo.getTotalAbility());
                        oldPalaceFloor.setDecorationSimpleList(palaceFloorInfo.getDecorationSimpleList());
                        oldPalaceFloor.setModifyTime(nowTime);
                    }
                    //移除幕宾
                    int aideCount = getPosMaxAideCount(myOldPos);
                    List<PalaceUserData> aideList = getPalaceAideList(enemyUserId);
                    if(null != aideList){
                        while (aideList.size() > aideCount){
                            PalaceUserData needRemoveData = null;
                            long maxJoinTime = 0;
                            for(PalaceUserData data : aideList){
                                if(data.getJoinTime() > maxJoinTime){
                                    needRemoveData = data;
                                    maxJoinTime = data.getJoinTime();
                                }
                            }
                            if(null != needRemoveData) {
                                removeAideFromList(needRemoveData.getAideUserId(), needRemoveData.getUserId(),
                                        CrossUserMgr.getServerIdByUserId(needRemoveData.getUserId()),
                                        ePalaceAideDismissType.SystemDismiss.getValue(), pos);
                            }
                        }
                    }

                    palaceFloorInfo.setUserId(userId);
                    palaceFloorInfo.setTotalAbility(myAbility);
                    palaceFloorInfo.setDecorationSimpleList(myDecorationSimpleList);
                    palaceFloorInfo.setModifyTime(nowTime);
                }
                int nowPos;
                if(isWin){
                    nowPos = myOldPos;
                }else {
                    nowPos = pos;
                }
                clearAideJoinApply(enemyUserId, isWin, pos, nowPos);
                notifyBattleRecord(enemyUserId, enemyServerId, userId, myUserInfo, isWin, pos, nowPos);
            }else {
                PalaceFloorInfo enemyPalaceFloorInfo = palaceFloorInfoMap.get(pos);
                if (null != enemyPalaceFloorInfo && enemyPalaceFloorInfo.getUserId() > 0) {
                    return GameErrorCode.E_ESTATE_WAR_FLOOR_CHANGE;
                }
                PalaceFloorConfig palaceFloorConfig = palaceFloorConfigMap.get(pos);
                if(null == palaceFloorConfig){
                    return GameErrorCode.E_PALACE_FLOOR_POS_NO_FOUND;
                }
                enemyAbility = palaceFloorConfig.getNpcEarnSpeed();
                //比拼赚速
                int addition = getTitleAddition(myTitleList);
                myValue = new BigDecimal(myAbility).multiply(BigDecimal.valueOf(addition)).
                        divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP);
                enemyValue = new BigDecimal(enemyAbility);
                if(myValue.compareTo(enemyValue) > 0){
                    isWin = true;
                }
                if(isWin){
                    if(null != oldPalaceFloor){//之前有位置
                        oldPalaceFloor.setUserId(0);
                        oldPalaceFloor.setModifyTime(System.currentTimeMillis());
                    }
                    PalaceFloorInfo palaceFloorInfo;
                    if(palaceFloorInfoMap.containsKey(pos)){
                        palaceFloorInfo = palaceFloorInfoMap.get(pos);
                    }else {
                        palaceFloorInfo = new PalaceFloorInfo();
                        palaceFloorInfo.setActivityId(getActivityId());
                        palaceFloorInfo.setPos(pos);
                        palaceFloorInfo.setInsertOption();
                        palaceFloorInfoMap.put(pos, palaceFloorInfo);
                    }
                    palaceFloorInfo.setUserId(userId);
                    palaceFloorInfo.setTotalAbility(myAbility);
                    palaceFloorInfo.setDecorationSimpleList(myDecorationSimpleList);
                    palaceFloorInfo.setModifyTime(System.currentTimeMillis());
                }
            }
            CrossAutoLogMgr.add(new LogPalaceBattle(getActivityId(), userId, myOldPos, pos, myAbility,
                    StringUtils.listToString(myTitleList, ","), myValue.toBigInteger(), enemyUserId, enemyAbility,
                    StringUtils.listToString(enemyTitleList, ","), enemyValue.toBigInteger(), isWin));
        }
        if(isWin) {
            //通知职位变更
            List<PalaceUserData> aideList = getPalaceAideList(userId);
            if(null != aideList && aideList.size() > 0){
                for(PalaceUserData data : aideList){
                    notifyAide(data.getUserId(), CrossUserMgr.getServerIdByUserId(data.getUserId()), pos,
                            ePalaceAideDismissType.Default.getValue(), 0, 0, "", userId);
                }
            }
            //打的玩家
            if(enemyUserId > 0) {
                aideList = getPalaceAideList(enemyUserId);
                if(null != aideList && aideList.size() > 0){
                    for(PalaceUserData data : aideList){
                        notifyAide(data.getUserId(), CrossUserMgr.getServerIdByUserId(data.getUserId()), myOldPos,
                                ePalaceAideDismissType.Default.getValue(), pos, 0, "", enemyUserId);
                    }
                }
                addBattleNotice(pos, isWin, userId, myUserInfo, enemyUserId, CrossUserMgr.getUserBaseInfo(enemyUserId));
            }
        }
        EstateWarProto.PalaceBattleRespMsg.Builder respMsg = EstateWarProto.PalaceBattleRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setIsWin(isWin);
        respMsg.setMyAbility(myAbility.toString());
        respMsg.addAllMyTitleList(myTitleList);
        respMsg.setEnemyAbility(enemyAbility.toString());
        if(null != enemyTitleList) {
            respMsg.addAllEnemyTitleList(enemyTitleList);
        }
        if(isWin) {
            if (null != oldPalaceFloor && enemyUserId > 0) {
                EstateWarProto.PalaceFloorTempMsg.Builder oldPalaceMsg = parsePalaceFloorTempMsg(oldPalaceFloor);
                respMsg.setOldPos(oldPalaceMsg);
            }
            respMsg.setNowPos(parsePalaceFloorTempMsg(palaceFloorInfoMap.get(pos)));
        }
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.S_PALACE_CROSS_BATTLE_RESP, respMsg);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
        return 0;
    }

    private List<Integer> getInTimeTitleList(List<DecorationSimple> decorationSimpleList){
        List<Integer> dataList = new ArrayList<>();
        if(null != decorationSimpleList){
            long nowTime = System.currentTimeMillis() / 1000;
            for(DecorationSimple data : decorationSimpleList){
                if(data.getEndTime() == 0 || data.getEndTime() > nowTime){
                    dataList.add(data.getDecorationId());
                }
            }
        }
        return dataList;
    }

    private int getTitleAddition(List<Integer> titleList){
        int addition = 1000;
        if(null != titleList){
            for(int titleId : titleList){
                GoodsInfo goodsInfo = GoodsMgr.getGoodsInfo(titleId);
                int titleLv = 0;
                if(null != goodsInfo){
                    String[] paramArr = goodsInfo.getExtendParam().split("\\|");
                    if(paramArr.length >= 5){
                        titleLv = Integer.parseInt(paramArr[4]);
                        addition += getTitleAdditionByLv(titleLv);
                    }
                }
            }
        }
        return addition;
    }

    private int getTitleAdditionByLv(int titleLv){
        if(titleLv < 1){
            return 0;
        }
        if(titleLv > PALACE_TITLE_ADDITION_LIST.size()){
            titleLv = PALACE_TITLE_ADDITION_LIST.size();
        }
        return PALACE_TITLE_ADDITION_LIST.get(titleLv - 1);
    }

    private void clearAideJoinApply(long userId, boolean isWin, int oldPos, int nowPos){
        if(isWin) {//被打败了，需要清除申请
            List<PalaceAideJoinApply> dataList = getPalaceAideJoinApplyList(userId);
            long nowTime = System.currentTimeMillis();
            Map<String, PalaceAideJoinApply> applyMap = aideJoinApplyMap.get(userId);
            for (PalaceAideJoinApply data : dataList) {
                data.setDeal(true);
                data.setDealTime(nowTime);
                if(null != applyMap){
                    applyMap.remove(data.getApplyUid());
                }
            }
        }
    }

    private void notifyBattleRecord(long userId, long serverId, long enemyUserId, UserBaseInfo enemyUserInfo, boolean isWin,
                                    int oldPos, int nowPos){
        EstateWarProto.PalaceBattleRecordNotifyMsg.Builder notifyMsg = EstateWarProto.PalaceBattleRecordNotifyMsg.newBuilder();
        notifyMsg.setActivityId(getActivityId());
        notifyMsg.setUserId(userId);
        notifyMsg.setIsWin(isWin);
        notifyMsg.setEnemyUserId(enemyUserId);
        notifyMsg.setEnemyUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(enemyUserInfo));
        notifyMsg.setOldPos(oldPos);
        notifyMsg.setNowPos(nowPos);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.S_PALACE_CROSS_BATTLE_RECORD_NOTIFY, notifyMsg);
        MessageHelper.sendPacket(serverId, 0, pbMsg);
    }

    private void addBattleNotice(int pos, boolean isWin, long userId, UserBaseInfo userBaseInfo, long enemyUserId, UserBaseInfo enemyBaseInfo){
        PalaceBattleNotice palaceBattleNotice = new PalaceBattleNotice();
        palaceBattleNotice.setNoticeUid(UUIDHelper.randomUUID(CrossBattleServer.getInstance().getServerId() + ""));
        palaceBattleNotice.setActivityId(getActivityId());
        palaceBattleNotice.setNoticeTime(System.currentTimeMillis());
        palaceBattleNotice.setPos(pos);
        palaceBattleNotice.setWin(isWin);
        palaceBattleNotice.setUserId(userId);
        palaceBattleNotice.setUserInfo(userBaseInfo);
        palaceBattleNotice.setEnemyUserId(enemyUserId);
        palaceBattleNotice.setEnemyUserInfo(enemyBaseInfo);
        palaceBattleNotice.setInsertOption();
        synchronized (palaceBattleNoticeList) {
            palaceBattleNoticeList.add(palaceBattleNotice);
            while (palaceBattleNoticeList.size() > GameConfig.PALACE_BATTLE_NOTICE_MAX_COUNT){
                PalaceBattleNotice data = palaceBattleNoticeList.get(0);
                if(!data.isDirty()){
                    palaceBattleNoticeList.remove(0);
                }else {
                    break;
                }
            }
        }
    }

    /**
    * 描述：膜拜获取榜首数据
    * 作者：zrq
    * 时间：2022/2/11
    * 参数：

    * 返回值：
    **/
    public int worship(long serverId, long userId){
        EstateWarProto.PalaceWorshipRespMsg.Builder respMsg = worship();
        if (respMsg.getRet() != 0) {
            return respMsg.getRet();
        }
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.S_PALACE_WORSHIP_CROSS_RESP, respMsg);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
        return 0;
    }

    public EstateWarProto.PalaceWorshipRespMsg.Builder worship(){
        EstateWarProto.PalaceWorshipRespMsg.Builder respMsg = EstateWarProto.PalaceWorshipRespMsg.newBuilder();
        if(palaceFloorInfoMap.size() <= 0){
            respMsg.setRet(GameErrorCode.E_ESTATE_WAR_WORSHIP_NO_DATA);
            return respMsg;
        }
        List<PalaceFloorInfo> tempList = new ArrayList<>(palaceFloorInfoMap.values());
        int maxIndex = palaceFloorConfigMap.size();
        PalaceFloorInfo topFloor = null;
        for(PalaceFloorInfo data : tempList){
            if(data.getUserId() > 0 && data.getPos() < maxIndex){
                topFloor = data;
                maxIndex = data.getPos();
            }
        }
        if(null == topFloor){
            respMsg.setRet(GameErrorCode.E_ESTATE_WAR_WORSHIP_NO_DATA);
            return respMsg;
        }
        respMsg.setRet(0);
        respMsg.setUserData(parsePalaceFloorTempMsg(topFloor));
        return respMsg;
    }

    public List<PalaceAideJoinApply> getPalaceAideJoinApplyList(long userId){
        Map<String, PalaceAideJoinApply> applyMap = aideJoinApplyMap.get(userId);
        if(null != applyMap){
            List<PalaceAideJoinApply> dataList = new ArrayList<>(applyMap.values());
            Iterator<PalaceAideJoinApply> iterator = dataList.iterator();
            while (iterator.hasNext()) {
                PalaceAideJoinApply data = iterator.next();
                if (data.isDeal()) {
                    iterator.remove();//使用迭代器的删除方法删除
                }
            }
            return dataList;
        }
        return new ArrayList<>();
    }

    /**
     * 描述：申请成为幕宾
     * 作者：zrq
     * 时间：2022/1/27
     * 参数：

     * 返回值：
     **/
    public int applyAide(long applyUerId, UserBaseInfo applyUserInfo, long userId, long serverId, boolean isSameUnion){
        //更新数据一下，无关逻辑
        CrossUserMgr.updateUserBaseInfo(applyUerId, applyUserInfo);

        if(!isOverPalaceAideDismissCDTime(userId, applyUerId)){
            return GameErrorCode.E_PALACE_AIDE_BE_DISMISS_TIME_NO_ENOUGH;
        }
        boolean onlyUnionMemberJoin = false;
        PalaceUserData palaceUserData = palaceUserDataMap.get(userId);
        if(null != palaceUserData){
            onlyUnionMemberJoin = palaceUserData.isOnlyUnionMemberJoin();
        }
        if(onlyUnionMemberJoin && !isSameUnion){
            return GameErrorCode.E_PALACE_AIDE_ONLY_UNION_MEMBER_JOIN;
        }
        PalaceUserData applyUserData = palaceUserDataMap.get(applyUerId);
        if(null != applyUserData && applyUserData.getAideUserId() > 0){
            return GameErrorCode.E_PALACE_ALREADY_AIDE;
        }
        int pos = getUserPos(userId);
        if(pos <= 0){
            return GameErrorCode.E_PALACE_AIDE_JOIN_APPLY_NO_AIDE_SITE;
        }
        // 超过幕宾最大数量不可申请
        int maxCount = getPosMaxAideCount(pos);
        List<PalaceUserData> palaceUserDataList = getPalaceAideList(userId);
        if (null != palaceUserDataList && palaceUserDataList.size() >= maxCount) {
            return GameErrorCode.E_PALACE_AIDE_COUNT_OVER;
        }
        PalaceFloorConfig palaceFloorConfig = palaceFloorConfigMap.get(pos);
        if(null == palaceFloorConfig){
            return GameErrorCode.E_PALACE_AIDE_JOIN_APPLY_NO_AIDE_SITE;
        }
        if(palaceFloorConfig.getRecruitNum() <= 0){
            return GameErrorCode.E_PALACE_AIDE_JOIN_APPLY_NO_AIDE_SITE;
        }
        if(!aideJoinApplyMap.containsKey(userId)){
            synchronized (aideJoinApplyMap){
                if(!aideJoinApplyMap.containsKey(userId)){
                    aideJoinApplyMap.put(userId, new ConcurrentHashMap<>());
                }
            }
        }
        Map<String, PalaceAideJoinApply> applyMap = aideJoinApplyMap.get(userId);
        PalaceAideJoinApply joinApply = new PalaceAideJoinApply();
        joinApply.setApplyUid(UUIDHelper.randomUUID(CrossBattleServer.getInstance().getServerId() + ""));
        joinApply.setActivityId(getActivityId());
        joinApply.setUserId(userId);
        joinApply.setApplyUserId(applyUerId);
        joinApply.setApplyTime(System.currentTimeMillis());
        synchronized (applyMap){
            for(PalaceAideJoinApply data : applyMap.values()){
                if(data.getApplyUserId() == applyUerId && !data.isDeal()){
                    return GameErrorCode.E_PALACE_AIDE_JOIN_ALREADY_APPLY;
                }
            }
            applyMap.put(joinApply.getApplyUid(), joinApply);
        }

        //同步申请
        List<PalaceAideJoinApply> syncList = new ArrayList<>();
        syncList.add(joinApply);
        EstateWarProto.PalaceAideApplyListMsg.Builder listMsg = CrossPalaceActivityMgr.parsePalaceAideApplyListMsg(syncList);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.U_PALACE_AIDE_APPLY_SYNC, listMsg);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
        return 0;
    }

    /**
     * 描述：处理幕宾请求
     * 作者：zrq
     * 时间：2022/2/8
     * 参数：

     * 返回值：
     **/
    public int dealAideApply(long userId, long serverId, int dealType, List<String> applyUidList){
        if(1 == dealType){//同意
            return agreeAideApply(userId, serverId, applyUidList);
        }else if(2 == dealType){//拒绝
            return refuseAideApply(userId, serverId, applyUidList);
        }else {
            return GameErrorCode.E_PALACE_AIDE_JOIN_APPLY_DEAL_TYPE_ERROR;
        }
    }

    public int agreeAideApply(long userId, long serverId, List<String> applyUidList){
        long nowTime = System.currentTimeMillis();
        Map<String, PalaceAideJoinApply> applyMap = aideJoinApplyMap.get(userId);
        for(String applyUid : applyUidList){
            PalaceAideJoinApply data = applyMap.get(applyUid);
            if(null == data){
                return GameErrorCode.E_PALACE_AIDE_JOIN_APPLY_NO_FOUND;
            }
            if(data.isDeal()){
                applyMap.remove(applyUid);
                return GameErrorCode.E_PALACE_AIDE_JOIN_APPLY_NO_FOUND;
            }
            //添加幕宾
            int ret = addPalaceAide(userId, serverId, data);

            //移除申请
            data.setDeal(true);
            data.setDealTime(nowTime);
            //移除申请
            applyMap.remove(applyUid);
            if(0 != ret){
                return ret;
            }
        }
        return 0;
    }

    public List<PalaceUserData> getPalaceAideList(long userId){
        return palaceAideMap.get(userId);
    }

    private synchronized int addPalaceAide(long userId, long serverId, PalaceAideJoinApply palaceAideJoinApply){
        PalaceUserData palaceUserData = palaceUserDataMap.get(palaceAideJoinApply.getApplyUserId());
        if(null != palaceUserData && palaceUserData.getAideUserId() > 0){//已经是别人幕宾了
            return GameErrorCode.E_PALACE_ALREADY_AIDE;
        }
        addPalaceUserDataIfNoExist(palaceAideJoinApply.getApplyUserId());
        long nowTime = System.currentTimeMillis();
        palaceUserData = palaceUserDataMap.get(palaceAideJoinApply.getApplyUserId());
        palaceUserData.setActivityId(getActivityId());
        palaceUserData.setUserId(palaceAideJoinApply.getApplyUserId());

        if(!palaceAideMap.containsKey(userId)){
            synchronized (palaceAideMap){
                if(!palaceAideMap.containsKey(userId)){
                    palaceAideMap.put(userId, new ArrayList<>());
                }
            }
        }
        int pos = getUserPos(userId);
        int maxCount = getPosMaxAideCount(pos);
        List<PalaceUserData> palaceUserDataList = getPalaceAideList(userId);
        synchronized (palaceUserDataList){
            if(palaceUserDataList.size() >= maxCount){
                return GameErrorCode.E_PALACE_AIDE_COUNT_OVER;
            }
            for(PalaceUserData data : palaceUserDataList){
                if(data.getAideUserId() == palaceAideJoinApply.getApplyUserId()){//已经是幕宾了
                    return GameErrorCode.E_PALACE_ALREADY_AIDE;
                }
            }
            //加入成功
            palaceUserData.setAideUserId(userId);
            palaceUserData.setJoinTime(nowTime);

            palaceUserDataList.add(palaceUserData);
        }
        //通知幕宾
        int aidePos = getUserPos(palaceUserData.getAideUserId());
        notifyAide(palaceUserData.getUserId(), CrossUserMgr.getServerIdByUserId(palaceUserData.getUserId()), aidePos,
                ePalaceAideDismissType.Default.getValue(), aidePos, 0, "", userId);
        return 0;
    }

    public int refuseAideApply(long userId, long serverId, List<String> applyUidList){
        long nowTime = System.currentTimeMillis();
        Map<String, PalaceAideJoinApply> applyMap = aideJoinApplyMap.get(userId);
        for(String applyUid : applyUidList){
            PalaceAideJoinApply data = applyMap.get(applyUid);
            if(null == data){
                continue;
            }
            if(data.isDeal()){
                applyMap.remove(applyUid);
            }
            //移除申请
            data.setDeal(true);
            data.setDealTime(nowTime);
            applyMap.remove(applyUid);
        }
        return 0;
    }

    private void notifyAide(long userId, long serverId, int underAide, int type, int oldUnderAide, long opServerId, String opNickName,
                            long opUserId){
        EstateWarProto.PalaceAideNotifyMsg.Builder notifyMsg = EstateWarProto.PalaceAideNotifyMsg.newBuilder();
        notifyMsg.setActivityId(getActivityId());
        notifyMsg.setUserId(userId);
        notifyMsg.setUnderAide(underAide);
        notifyMsg.setType(type);
        notifyMsg.setOpUserId(opUserId);
        if(ePalaceAideDismissType.PlayerDismiss.getValue() == type || ePalaceAideDismissType.SystemDismiss.getValue() == type){
            notifyMsg.setOldUnderAide(oldUnderAide);
            notifyMsg.setOpServerId(opServerId);
            notifyMsg.setOpNickName(opNickName);
        }
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.S_PALACE_CROSS_AIDE_NOTIFY, notifyMsg);
        MessageHelper.sendPacket(serverId, 0, pbMsg);
    }

    public int queryAide(long userId, long serverId, long queryUserId, long queryServerId){
        List<PalaceUserData> dataList = getPalaceAideList(queryUserId);
        boolean isAideOrApply = false;
        if(null != dataList){
            for(PalaceUserData data : dataList){
                if(data.getUserId() == userId){
                    isAideOrApply = true;
                    break;
                }
            }
        }
        if(!isAideOrApply){
            List<PalaceAideJoinApply> applyList = getPalaceAideJoinApplyList(queryUserId);
            for(PalaceAideJoinApply data : applyList){
                if(data.getApplyUserId() == userId){
                    isAideOrApply = true;
                    break;
                }
            }
        }
        EstateWarProto.PalaceAideQueryRespMsg.Builder respMsg = EstateWarProto.PalaceAideQueryRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setIsAideOrApply(isAideOrApply);
        respMsg.setDataList(CrossPalaceActivityMgr.parsePalaceAideListMsg(dataList));
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.U_PALACE_AIDE_LIST, respMsg);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
        return 0;
    }

    /**
     * 描述：遣散幕宾
     * 作者：zrq
     * 时间：2022/2/9
     * 参数：

     * 返回值：
     **/
    public int dismissAide(long userId, long serverId, long dismissUserId, long dismissServerId){
        removeAideFromList(userId, dismissUserId, dismissServerId, ePalaceAideDismissType.PlayerDismiss.getValue(), getUserPos(userId));
        addPalaceAideDismissData(userId, dismissUserId);
        return 0;
    }

    public void addPalaceAideDismissData(long userId, long dismissUserId){
        if(!palaceAideDismissDataMap.containsKey(userId)){
            synchronized (palaceAideDismissDataMap){
                if(!palaceAideDismissDataMap.containsKey(userId)){
                    palaceAideDismissDataMap.put(userId, new ConcurrentHashMap<>());
                }
            }
        }
        Map<Long, PalaceAideDismissData> dataMap = getPalaceAideDismissDataMap(userId);
        if(!dataMap.containsKey(dismissUserId)){
            synchronized (dataMap){
                if(!dataMap.containsKey(dismissUserId)){
                    PalaceAideDismissData data = new PalaceAideDismissData();
                    data.setActivityId(getActivityId());
                    data.setUserId(userId);
                    data.setDismissUserId(dismissUserId);
                    data.setInsertOption();
                    dataMap.put(dismissUserId, data);
                }
            }
        }
        PalaceAideDismissData data = dataMap.get(dismissUserId);
        if(null != data){
            data.setDismissTime(System.currentTimeMillis());
        }
    }

    public Map<Long, PalaceAideDismissData> getPalaceAideDismissDataMap(long userId){
        return palaceAideDismissDataMap.get(userId);
    }

    public long getAideDismissTime(long userId, long destUserId){
        long dismissTime = 0;
        Map<Long, PalaceAideDismissData> dataMap = getPalaceAideDismissDataMap(userId);
        if(null != dataMap){
            PalaceAideDismissData data = dataMap.get(destUserId);
            if(null != data){
                dismissTime = data.getDismissTime();
            }
        }
        return dismissTime;
    }

    private void removeAideFromList(long aideUserId, long destUserId, long destServerId, int type, int oldUnderAide){
        List<PalaceUserData> dataList = getPalaceAideList(aideUserId);
        if(null != dataList){
            UserBaseInfo aideUserInfo = CrossUserMgr.getUserBaseInfo(aideUserId);
            synchronized (dataList){
                Iterator<PalaceUserData> iterator = dataList.iterator();
                while (iterator.hasNext()) {
                    PalaceUserData data = iterator.next();
                    if (data.getUserId() == destUserId) {
                        data.setAideUserId(0);
                        iterator.remove();//使用迭代器的删除方法删除
                        notifyAide(destUserId, destServerId, 0, type, oldUnderAide, aideUserInfo.getServerId(),
                                aideUserInfo.getNickName(), aideUserId);
                    }
                }
            }
        }
    }

    public int relieveAide(long userId, long serverId){
        PalaceUserData palaceUserData = palaceUserDataMap.get(userId);
        if(null != palaceUserData && palaceUserData.getAideUserId() > 0){
            long aideUserId = palaceUserData.getAideUserId();
            removeAideFromList(palaceUserData.getAideUserId(), userId, serverId, ePalaceAideDismissType.Default.getValue(), 0);
            synchronized (palaceFloorInfoMap) {
                PalaceFloorInfo palaceFloorInfo = null;
                for (PalaceFloorInfo data : palaceFloorInfoMap.values()) {
                    if (data.getUserId() == aideUserId) {
                        palaceFloorInfo = data;
                        break;
                    }
                }
                if(null != palaceFloorInfo) {
                    palaceFloorInfo.setModifyTime(System.currentTimeMillis());
                }
            }
        }
        return 0;
    }

    /**
    * 描述：如果不存在，增加玩家数据
    * 作者：zrq
    * 时间：2022/2/17
    * 参数：

    * 返回值：
    **/
    private synchronized void addPalaceUserDataIfNoExist(long userId){
        if(!palaceUserDataMap.containsKey(userId)){
            PalaceUserData palaceUserData = new PalaceUserData();
            palaceUserData.setActivityId(getActivityId());
            palaceUserData.setUserId(userId);
            palaceUserData.setInsertOption();
            palaceUserDataMap.put(userId, palaceUserData);
        }
    }

    /**
     * 描述：膜拜获取榜首数据
     * 作者：zrq
     * 时间：2022/2/11
     * 参数：

     * 返回值：
     **/
    public int aideJoinSetting(long userId, long serverId, boolean onlyUnionMemberJoin, boolean needResponse){
        addPalaceUserDataIfNoExist(userId);
        PalaceUserData palaceUserData = palaceUserDataMap.get(userId);
        if(null != palaceUserData){
            palaceUserData.setOnlyUnionMemberJoin(onlyUnionMemberJoin);
        }
        EstateWarProto.PalaceAideJoinSettingCrossRespMsg.Builder respMsg = EstateWarProto.PalaceAideJoinSettingCrossRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setUserId(userId);
        respMsg.setActivityId(getActivityId());
        respMsg.setNeedResponse(needResponse);
        respMsg.setOnlyUnionMemberJoin(onlyUnionMemberJoin);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.S_PALACE_AIDE_JOIN_SETTING_RESP, respMsg);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
        return 0;
    }

    public EstateWarProto.PalaceFloorTempMsg.Builder parsePalaceFloorTempMsg(PalaceFloorInfo data) {
        if(null == data){
            return null;
        }
        EstateWarProto.PalaceFloorTempMsg.Builder msg = EstateWarProto.PalaceFloorTempMsg.newBuilder();
        msg.setUserId(data.getUserId());
        msg.setPos(data.getPos());
        if(data.getUserId() > 0) {
            msg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(CrossUserMgr.getUserBaseInfo(data.getUserId())));
            int aideCount = 0;
            List<PalaceUserData> palaceUserDataList = getPalaceAideList(data.getUserId());
            if (null != palaceUserDataList) {
                aideCount = palaceUserDataList.size();
            }
            msg.setAideCount(aideCount);
            msg.setBaseAbility(data.getTotalAbility().toString());
            List<Integer> titleList = getInTimeTitleList(data.getDecorationSimpleList());
            msg.addAllTitleList(titleList);
        }
        return msg;
    }

    private int getUserPos(long userId){
        for(PalaceFloorInfo palaceFloorInfo : palaceFloorInfoMap.values()){
            if(palaceFloorInfo.getUserId() == userId){
                return palaceFloorInfo.getPos();
            }
        }
        return 0;
    }

    public void syncPalaceUserData(long userId, long serverId){
        EstateWarProto.PalaceUserDataSyncRespMsg.Builder syncMsg = EstateWarProto.PalaceUserDataSyncRespMsg.newBuilder();
        syncMsg.setActivityId(getActivityId());
        syncMsg.setUserId(userId);
        syncMsg.setPos(getUserPos(userId));
        PalaceUserData palaceUserData = palaceUserDataMap.get(userId);
        if(null != palaceUserData){
            syncMsg.setOnlyUnionMemberJoin(palaceUserData.isOnlyUnionMemberJoin());
            int aidePos = 0;
            long aideUserId = palaceUserData.getAideUserId();
            if(aideUserId > 0){
                aidePos = getUserPos(aideUserId);
            }
            syncMsg.setUnderAide(aidePos);
        }else {
            syncMsg.setOnlyUnionMemberJoin(false);
            syncMsg.setUnderAide(0);
        }
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.S_PALACE_USER_DATA_SYNC_RESP, syncMsg);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
    }

    private int getPosMaxAideCount(int pos){
        int aideCount = 0;
        if(pos > 0){
            PalaceFloorConfig palaceFloorConfig = palaceFloorConfigMap.get(pos);
            if(null != palaceFloorConfig){
                aideCount = palaceFloorConfig.getRecruitNum();
            }
        }
        return aideCount;
    }

    private long getAideLastJoinTime(long userId){
        List<PalaceUserData> aideList = getPalaceAideList(userId);
        long lastJoinTime = 0;
        if(null != aideList){
            for(PalaceUserData data : aideList){
                if(data.getJoinTime() > lastJoinTime){
                    lastJoinTime = data.getJoinTime();
                }
            }
        }
        return lastJoinTime;
    }

    public void syncDecorationSimple(long userId, List<DecorationSimple> decorationSimpleList){
        synchronized (palaceFloorInfoMap) {//锁起来，慢慢找
            PalaceFloorInfo palaceFloorInfo = null;
            for (PalaceFloorInfo data : palaceFloorInfoMap.values()) {
                if (data.getUserId() == userId) {
                    palaceFloorInfo = data;
                    break;
                }
            }
            if (null != palaceFloorInfo) {
                palaceFloorInfo.setDecorationSimpleList(decorationSimpleList);
                palaceFloorInfo.setModifyTime(System.currentTimeMillis());
            }
        }
    }

    public void syncAbility(Map<Long, BigInteger> abilityMap){
        synchronized (palaceFloorInfoMap) {//锁起来，慢慢找
            for(Map.Entry<Long, BigInteger> entryData : abilityMap.entrySet()) {
                PalaceFloorInfo palaceFloorInfo = null;
                for (PalaceFloorInfo data : palaceFloorInfoMap.values()) {
                    if (data.getUserId() == entryData.getKey()) {
                        palaceFloorInfo = data;
                        break;
                    }
                }
                if (null != palaceFloorInfo) {
                    palaceFloorInfo.setTotalAbility(entryData.getValue());
                    palaceFloorInfo.setModifyTime(System.currentTimeMillis());
                }
            }
        }
    }

    private boolean isOverPalaceAideDismissCDTime(long userId, long applyUserId){
        long dismissTime = getAideDismissTime(userId, applyUserId);
        return System.currentTimeMillis() > dismissTime + GameConfig.PALACE_AIDE_DISMISS_REAPPLY_TIME * 1000;
    }

    private long getLastPalaceAideDismissTime(long userId){
        long lastTime = 0;
        Map<Long, PalaceAideDismissData> dataMap = getPalaceAideDismissDataMap(userId);
        if(null != dataMap) {
            for (PalaceAideDismissData data : dataMap.values()) {
                if (data.getDismissTime() > lastTime) {
                    lastTime = data.getDismissTime();
                }
            }
        }
        return lastTime;
    }

    private int getTitleType(int pos){
        int titleType = 0;
        if(pos > 0){
            PalaceFloorConfig palaceFloorConfig = palaceFloorConfigMap.get(pos);
            if(null != palaceFloorConfig){
                titleType = palaceFloorConfig.getTitleType();
            }
        }
        return titleType;
    }
}
